Skip to content

Load Mermaid/Highlight.js only where used; fix heading hierarchy and image attributes - #882

Merged
richarddushime merged 4 commits into
mainfrom
worktree-seo-conditional-assets
Sep 2, 2026
Merged

Load Mermaid/Highlight.js only where used; fix heading hierarchy and image attributes#882
richarddushime merged 4 commits into
mainfrom
worktree-seo-conditional-assets

Conversation

@LukasWallrich

@LukasWallrich LukasWallrich commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Closes #865, #860, #869, #861. Related: #870 (duplicate preconnects, item 6).

What changes

Conditional Mermaid / Highlight.js (#865)

  • diagram and highlight site params default to false. site_head.html decides per page: front matter (highlight: true / diagram: true) wins; otherwise the library loads only when the page's Markdown content contains a code block (resp. a Mermaid block). Detection runs on .Content, so the cite modal's <pre><code class="tex hljs"> on every page does not trigger it.
  • Both libraries load with defer; their only callers sit in academic.js's document-ready handler.
  • Result on a full build: Highlight.js loads on one page (/manuscript/, forced via front matter because its code block lives in a headless section file); Mermaid loads on none; the homepage requests neither.

Search index (#861)

Heading hierarchy (#860)

  • Search overlay heading is an h2 (same visual size via CSS).
  • Page-builder pages get exactly one h1: a hero widget renders a visible one, otherwise widget_page.html emits a visually hidden h1 from the page title (site title on the homepage). All section titles from widget partials are h2 with unchanged size and divider.
  • Author profiles: the person's name is the h1.
  • Site-wide, pages with more than one h1 drop from 5287 to 13. The remaining 13 are content-level # headings inside widget sections (community, mission, testimonials, publications, …) and shortcode-emitted h1s; those are content edits and left out here.

Images (#869)

  • Every template <img> now has an alt decision. The award logos in content/awards/awards.md get alt="" because the adjacent text names the awarding organisation; the ELD CAMA diagram gets a descriptive alt.
  • Intrinsic width/height added to announcement cards, list cards, resource cards, avatars, page-header featured images, the CC badge, and featurette images (via a new functions/static_img_dims partial that reads static raster files at build time). CSS keeps those images fluid (height: auto). Homepage: 15 of 24 images now carry dimensions; the rest are the SVG logo, SDG badges in a shortcode, the chatbot icon and one content image.

Cleanup

  • Duplicate Google Fonts preconnects removed from chatbot.html.

Regression check

scripts/check_seo_html.py public parses every built page and fails on: an <h1>Search</h1>, Mermaid/Highlight.js on the homepage, a library loaded on a page without a matching code block (or vice versa), or an <img> without an alt attribute. It also reports pages with zero or several h1s and the homepage image dimension count. It runs after the Hugo build in deploy.yaml.

Verified

  • Full local build passes all four checks.
  • Screenshots compared against a baseline build: homepage sections, search overlay, author profile and featurette images look the same.

Not in this PR

#859, #864, #866, #867, #868 need expert review or design decisions.

🤖 Generated with Claude Code

…image attributes

- Mermaid and Highlight.js are opt-in: they load on pages whose Markdown
  content has a code block (or `highlight`/`diagram` front matter), with
  `defer`; site params default to false (#865).
- Search index fetch shows a failure message and allows a retry (#861).
- Search overlay heading is an h2; homepage and page-builder section titles
  are h2 under one page h1 (visible hero, or visually hidden page title);
  author profile name is the h1 (#860).
- Every template image has an alt decision; card, avatar, header and
  featurette images carry intrinsic width/height (#869).
- Duplicate Google Fonts preconnects removed from the chatbot partial.
- scripts/check_seo_html.py checks the built HTML for these rules and runs
  after the Hugo build in deploy.yaml.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011qVBTM5W7PENuS5gS1Nm7z
@LukasWallrich
LukasWallrich requested a review from a team as a code owner September 2, 2026 16:48
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

⚠️ Image files/references in png/jpg format detected

Note that we generally rely on webp format for this webpage, so please consider converting these images to WebP format and updating references accordingly.

References to image files:

  • layouts/partials/widgets/about_welcome.html: }}/hqdefault.jpg

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

✅ Spell Check Passed

No spelling issues found when checking 42 changed file(s)! 🎉

@LukasWallrich

LukasWallrich commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Staging Deployment Status

This PR has been successfully deployed to staging as part of an aggregated deployment.

Deployed at: 2026-09-02 22:22:19 UTC
Staging URL: https://staging.forrt.org

The staging site shows the combined state of all compatible open PRs.

Comment thread content/awards/awards.md Outdated

@richarddushime richarddushime left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@richarddushime
richarddushime merged commit 71f43e0 into main Sep 2, 2026
5 checks passed
@richarddushime
richarddushime deleted the worktree-seo-conditional-assets branch September 2, 2026 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Load Mermaid and Highlight.js only when needed

2 participants